<template>
  <div class="app-container">
    <div class="search-bar">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item prop="keywords">
          <el-input
            v-model="queryParams.keywords"
            placeholder="分类名称"
            clearable
            @keyup.enter="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
          <el-button type="success" icon="plus" @click="handleOpenDialog()">新增</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never">
      <el-table
        v-loading="loading"
        :data="categoryList"
        highlight-current-row
        row-key="id"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      >
        <el-table-column label="序号" align="center" width="80">
          <template #default="scope">
            {{ scope.$index + 1 }}
          </template>
        </el-table-column>
        <el-table-column label="分类名称" min-width="200">
          <template #default="scope">
            {{ scope.row.name }}
          </template>
        </el-table-column>
        <el-table-column label="权重" align="center" width="100" prop="sort" />
        <el-table-column label="状态" align="center" width="80">
          <template #default="scope">
            <el-tag v-if="scope.row.visible === 1" type="success">已上架</el-tag>
            <el-tag v-else type="info">已下架</el-tag>
          </template>
        </el-table-column>
        <el-table-column fixed="right" align="center" label="操作" width="220">
          <template #default="scope">
            <el-button
              type="primary"
              link
              size="default"
              icon="edit"
              @click.stop="handleOpenDialog(scope.row.id)"
            >
              编辑
            </el-button>
            <el-button
              :type="scope.row.visible === 1 ? 'danger' : 'warning'"
              link
              size="default"
              :icon="scope.row.visible === 1 ? 'Bottom' : 'Top'"
              @click.stop="handleDelete(scope.row)"
            >
              {{ scope.row.visible === 1 ? "下架" : "上架" }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 表单弹窗 -->
    <el-dialog v-model="dialog.visible" :title="dialog.title" width="450px" @close="resetForm">
      <el-form ref="menuFormRef" :model="formData" :rules="formRules" label-width="120px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="formData.name" placeholder="请输入分类名称" />
        </el-form-item>

        <el-form-item label="权重" prop="sort">
          <el-input-number v-model="formData.sort" :min="0" />
        </el-form-item>
        <el-form-item label="封面">
          <el-upload
            class="avatar-uploader"
            :show-file-list="false"
            :auto-upload="false"
            :on-change="handleFileChange"
            :before-upload="beforeAvatarUpload"
          >
            <div class="upload-container">
              <img v-if="formData.cover" :src="formData.cover" class="avatar" />
              <i v-else class="el-icon-plus avatar-uploader-icon">
                <el-icon><Plus /></el-icon>
              </i>
            </div>
          </el-upload>
        </el-form-item>
        <el-form-item label="是否启用" prop="visible">
          <el-switch v-model="formData.state" :active-value="1" :inactive-value="0" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialog.visible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import http from "@/http";
// 菜单类型枚举

// 菜单数据类型定义
interface MenuItem {
  id: string;
  name: string;
  sort: number;
  visible: number;
}

interface FormData {
  id?: string;
  name: string;
  sort: number; // ✅ 改为 sort（与表格字段一致）
  cover: string;
  state: number;
}

// 表单验证规则
const formRules = reactive({
  name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  sort: [{ required: true, message: "请输入权重", trigger: "blur" }],
});
import type { FormInstance } from "element-plus";

// 引用
const queryFormRef = ref(null);
const menuFormRef = ref<FormInstance | null>(null);

// 状态管理
const loading = ref(false);
const dialog = reactive({
  title: "新增菜单",
  visible: false,
});

// 查询参数
const queryParams = reactive({
  keywords: "",
});
interface CategoryInfo {
  id: string;
  name: string;
  sort: number; // ✅ 转换后的权重字段
  cover: string;
  visible: number; // ✅ 转换后的状态字段
}
const categoryList = ref<CategoryInfo[]>([]);

// 保存原始数据（用于搜索后重置）
const originalCategoryList = ref<CategoryInfo[]>([]);

// 初始菜单表单数据
const initialMenuFormData: FormData = {
  name: "",
  sort: 1,
  cover: "",
  state: 0,
};
// 原本地过滤逻辑替换为接口请求
async function handleQuery() {
  loading.value = true;
  try {
    const categoryArray = await http.getCategoryList(queryParams.keywords.trim());
    categoryArray.data = categoryArray;
    // 转换字段（weight → sort，state → visible）
    categoryList.value = categoryArray.data.map((item: any) => ({
      id: item.id,
      name: item.name,
      sort: item.weight, // 后端 weight → 前端 sort
      cover: item.cover,
      visible: item.state, // 后端 state → 前端 visible
    }));

    originalCategoryList.value = [...categoryList.value]; // 保存原始数组
  } catch (error) {
    console.error("获取分类失败：", error);
    categoryList.value = []; // 错误时赋空数组
  } finally {
    loading.value = false;
  }
}
// 菜单表单数据
const formData = ref<FormData>({ ...initialMenuFormData });

/**
 * 打开表单弹窗
 */
function handleOpenDialog(menuId?: string) {
  if (menuId) {
    const item = categoryList.value.find((item) => item.id === menuId);
    if (item) {
      formData.value = {
        id: item.id,
        name: item.name,
        sort: item.sort, // ✅ 读取转换后的 sort 字段
        cover: item.cover,
        state: item.visible, // 状态使用转换后的 visible（与表格一致）
      };
      dialog.title = "编辑分类"; // 建议统一名称为“分类”
    }
  } else {
    resetForm();
  }
  dialog.visible = true;
}

/**
 * 重置表单
 */
function resetForm() {
  formData.value = { ...initialMenuFormData };
  // @ts-ignore
  menuFormRef.value?.resetFields();
}

/**
 * 处理保存
 */
// 处理表单保存逻辑
const handleSave = async () => {
  // 1. 表单验证（必选）
  if (!menuFormRef.value) return;
  const isValid = await menuFormRef.value.validate();
  if (!isValid) return; // 验证失败则终止

  await uploadImage();

  console.log(formData.value.cover);

  console.log(formData.value);
  // 3. 区分“新增”和“编辑”操作，调用对应接口
  try {
    loading.value = true; // 显示加载状态

    if (formData.value.id) {
      // 编辑操作：调用更新接口
      await http.updateCategory(
        formData.value.id,
        formData.value.name,
        formData.value.sort,
        formData.value.cover,
        formData.value.state
      );
      ElMessage.success("编辑成功");
    } else {
      // 新增操作：调用创建接口
      await http.createCategory(
        formData.value.name,
        formData.value.sort,
        formData.value.cover,
        formData.value.state
      );
      ElMessage.success("新增成功");
    }

    // 4. 保存成功后关闭弹窗并刷新列表
    dialog.visible = false;
    handleQuery(); // 重新获取分类列表，刷新页面
  } catch {
    ElMessage.error("保存失败，请重试");
  } finally {
    loading.value = false; // 关闭加载状态
  }
};
/**
 * 处理下架/上架
 */
function handleDelete(row: MenuItem) {
  const action = row.visible === 1 ? "下架" : "上架"; // 1 表示上架，0 表示下架
  ElMessageBox.confirm(`确定要${action}菜单【${row.name}】吗？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: row.visible === 1 ? "warning" : "info",
  })
    .then(async () => {
      // 改为 async 函数，便于使用 await 调用接口
      loading.value = true;
      try {
        // 调用接口修改状态（传递菜单 ID）
        await http.changeCategoryState(row.id);

        ElMessage.success(`${action}成功`);
        // 刷新列表数据（根据实际列表刷新方法修改）
        handleQuery();
      } catch {
        ElMessage.error(`${action}失败，请联系管理员`);
      } finally {
        loading.value = false; // 无论成功失败，都关闭加载状态
      }
    })
    .catch(() => {
      ElMessage.info(`已取消${action}`);
    });
}
// 存储选中的文件（用于后续上传到后端）
// 存储选中的文件（用于上传到后端）
const selectedFile = ref<File | null>(null);
// 存储临时预览URL（用于组件卸载时释放）
const tempPreviewUrl = ref("");

// 文件选择变化时触发（预览）
const handleFileChange = (file: any) => {
  const rawFile = file.raw;
  if (!rawFile) return;

  // 1. 执行校验
  const isValid = beforeAvatarUpload(rawFile);
  if (!isValid) {
    formData.value.cover = "";
    selectedFile.value = null;
    tempPreviewUrl.value = "";
    return;
  }

  // 2. 生成临时预览URL（本地预览）
  const previewUrl = URL.createObjectURL(rawFile);
  formData.value.cover = previewUrl; // 触发img标签显示
  tempPreviewUrl.value = previewUrl; // 保存临时URL，用于后续释放

  // 3. 保存文件并自动上传
  selectedFile.value = rawFile;
};

// 上传图片到服务器
const uploadImage = async () => {
  if (!selectedFile.value) return;

  try {
    // 调用上传接口，获取文件名
    const result = await http.uploadImages(selectedFile.value);

    result.data = result;
    // 拼接可访问的URL（与后端配置的RequestPath一致）
    const imageUrl = `http://localhost:5000/images/${result.data.fileName}`;

    // 保存到formData，触发图片显示
    formData.value.cover = imageUrl;

    ElMessage.success("图片上传成功");
  } catch (error) {
    console.error("上传失败:", error);
    ElMessage.error("图片上传失败，请重试");
  }
};
// 上传前的校验
const beforeAvatarUpload = (file: File) => {
  const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
  if (!isJpgOrPng) {
    ElMessage.error("请上传JPG/PNG格式的图片");
    return false;
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    ElMessage.error("图片大小不能超过2MB");
    return false;
  }
  return true;
};

// 页面挂载时执行
onMounted(async () => {
  if (tempPreviewUrl.value) {
    URL.revokeObjectURL(tempPreviewUrl.value);
  }
  await handleQuery();
});
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.search-bar {
  margin-bottom: 20px;
}
.avatar-uploader {
  display: inline-block;
}

.upload-container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 150px;
  height: 150px;
  cursor: pointer;
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  transition: border-color 0.3s;
}

.upload-container:hover {
  border-color: #409eff;
}

.avatar {
  width: 80%;
  height: 80%;
  object-fit: cover;
  border-radius: 4px;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
}
</style>
